﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace UFrame
{
    public class BufferVerify
    {
        public class BufferInfo
        {
            public bool isFull = false; //是否接收完毕
            public int packageLen = 0; //包的长度
            public byte[] headAry = new byte[4];
            public byte[] opAry = new byte[4];
            public byte[] contentAry = new byte[4];
            public List<byte> receiveAllAry = new List<byte>(); //当前接受的所以字节
            public bool isHead = false;
            public bool isOP = false;
            public bool isContent = false;
            public int len; //当前接受的全部字节长度
            public int contentLen = 0; //正文长度
            
            public void Clear()
            {
                this.isFull = false;
                this.isHead = false;
                this.isContent = false;
                this.len = 0;
                receiveAllAry.RemoveRange(0,packageLen);
                len = receiveAllAry.Count;
                this.packageLen = 0;
            }

        }

        public int HeadLen = 4;
        public int HeadOP = 2;
        public int BufferLen = 0x7FFFFF;

       
        public BufferInfo ReceiveStream(Byte[] byteAry, BufferInfo info)
        {
            info.len += byteAry.Length;
            info.receiveAllAry.AddRange(byteAry);
            if (info.len < HeadLen && info.isHead == false) //还没读取完头部
            {
                return info;
            }

            if (info.len >= HeadLen && info.isHead == false) //读完头部了
            {
                Array.Copy(info.receiveAllAry.ToArray(), 0, info.headAry, 0, HeadLen);
                info.isHead = true;
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(info.headAry);
                }
                info.contentLen = (int) BitConverter.ToUInt32(info.headAry, 0) ;
                info.packageLen = (int) BitConverter.ToUInt32(info.headAry, 0) + HeadOP + HeadLen;
            }

            int headAll = HeadLen + HeadOP;
            if (info.len < headAll && info.isOP == false)
            {
                return info;
            }

            if (info.len >= headAll && info.isOP == false) //读取Op事件码
            {
                Array.Copy(info.receiveAllAry.ToArray(), HeadLen, info.opAry, 0, HeadOP);
                info.isOP = true;
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(info.opAry);
                }
            }

            int contentLen = HeadLen + HeadOP + info.contentLen; //小于完整的包体长度
            if (info.len < contentLen && info.isContent == false)
            {
                return info;
            }

            if (info.len >= contentLen)
            {
                info.contentAry = new byte[info.contentLen];
                Array.Copy(info.receiveAllAry.ToArray(), headAll, info.contentAry, 0, info.contentLen);
                info.isContent = true;
                info.isFull = true;
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(info.contentAry);
                }
            }

            return info;
        }

        public void SendStream(Byte[] sendAry)
        {
        }

        public byte[] SendRPC(ushort op, string json, Encoding encoding)
        {
            MemoryStream memStream = new MemoryStream();
            var content = encoding.GetBytes(json);
            memStream.Write(content, 0, content.Length);

            Int32 len = (Int32) memStream.Length;
            byte[] data = new byte[HeadLen + HeadOP + len];
            BitConverter.GetBytes(len).CopyTo(data, 0);
            BitConverter.GetBytes(op).CopyTo(data, HeadLen);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(data, 0, HeadLen);
                Array.Reverse(data, HeadLen, HeadOP);
            }

            memStream.ToArray().CopyTo(data, HeadLen + HeadOP);
            memStream.Close();
            return data;
        }
    }
}